package gew.services;

import gew.data.DimensionValue;
import gew.metadata.Queries;
import gew.utils.SqlUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.Singleton;

@Singleton
public class DimensionValueService {
    
    @EJB
    private QueryService queryService;
    
    private final HashMap<Queries, HashMap<Locale, HashMap<Integer, DimensionValue>>> dimById = new HashMap();
    private final HashMap<Queries, HashMap<Locale, HashMap<String, DimensionValue>>> dimByUrlCode = new HashMap();
    
    @PostConstruct
    public void init() {
        initMap(LocaleService.getLocaleEN(), Queries.CommodityDimensionValue);
        initMap(LocaleService.getLocaleRU(), Queries.CommodityDimensionValue);
        initMap(LocaleService.getLocaleEN(), Queries.CommodityGroupTypeDimensionValue);
        initMap(LocaleService.getLocaleRU(), Queries.CommodityGroupTypeDimensionValue);
        initMap(LocaleService.getLocaleEN(), Queries.PeriodDimensionValue);
        initMap(LocaleService.getLocaleRU(), Queries.PeriodDimensionValue);
        initMap(LocaleService.getLocaleEN(), Queries.CountryDimensionValue);
        initMap(LocaleService.getLocaleRU(), Queries.CountryDimensionValue);
        initMap(LocaleService.getLocaleEN(), Queries.TradeFlowDimensionValue);
        initMap(LocaleService.getLocaleRU(), Queries.TradeFlowDimensionValue);
        initMap(LocaleService.getLocaleEN(), Queries.IndicatorDimensionValue);
        initMap(LocaleService.getLocaleRU(), Queries.IndicatorDimensionValue);
        initMap(LocaleService.getLocaleEN(), Queries.SectionDimensionValue);
        initMap(LocaleService.getLocaleRU(), Queries.SectionDimensionValue);
    }
    
    private void initMap(Locale locale, Queries queryType) {
        List<DimensionValue> items = queryService.getDimensionValueItems(queryType, locale.getLanguage());
        if (!dimById.containsKey(queryType)) {
            dimById.put(queryType, new HashMap());
        }
        dimById.get(queryType).put(locale, new HashMap());
        if (!dimByUrlCode.containsKey(queryType)) {
            dimByUrlCode.put(queryType, new HashMap());
        }
        dimByUrlCode.get(queryType).put(locale, new HashMap());
        for (Integer i = 0; i < items.size(); i++) {
            if (items.get(i).getId() != 0) {
                dimById.get(queryType).get(locale).put(items.get(i).getId(), items.get(i));
                dimByUrlCode.get(queryType).get(locale).put(items.get(i).getUrlCode(), items.get(i));
            }
        }
    }
    
    public List<Integer> getIdByUrlCode(Locale locale, String urlCode, Queries queryType) {
        List<Integer> result = new ArrayList();
        String[] codes = urlCode.split(SqlUtils.HYPHEN);
        for (Integer i = 0; i < codes.length; i++) {
            if (dimByUrlCode.get(queryType).get(locale).containsKey(codes[i])) {
                result.add(dimByUrlCode.get(queryType).get(locale).get(codes[i]).getId());
            }
        }
        return result;
    }
    
    public String getIdsCSByUrlCode(Locale locale, String urlCode, Queries queryType) {
        List<String> result = new ArrayList();
        String[] codes = urlCode.split(SqlUtils.HYPHEN);
        for (Integer i = 0; i < codes.length; i++) {
            if (dimByUrlCode.get(queryType).get(locale).containsKey(codes[i])) {
                result.add(dimByUrlCode.get(queryType).get(locale).get(codes[i]).getId().toString());
            }
        }
        return String.join(SqlUtils.COMMA, result);
    }
    
    public Collection<DimensionValue> getAllValues(Locale locale, Queries queryType) {
        return dimById.get(queryType).get(locale).values();
    }
    
    public List<DimensionValue> getSelectedValues(List<Integer> ids, Locale locale, Queries queryType) {
        List<DimensionValue> result = new ArrayList();
        for (Integer i = 0; i < ids.size(); i++) {
            result.add(dimById.get(queryType).get(locale).get(ids.get(i)));
        }
        return result;
    }
    
    public String getUrlCodes(Queries queryType, List<Integer> ids, Locale locale) {
        return getUrlCodes(queryType, ids, locale, SqlUtils.COMMA.concat(SqlUtils.SPACE));
    }
    
    public String getUrlCodes(Queries queryType, List<Integer> ids, Locale locale, String separator) {
        List<String> urlCodes = new ArrayList<>();
        for (Integer i = 0; i < ids.size(); i++) {
            urlCodes.add(dimById.get(queryType).get(locale).get(ids.get(i)).getUrlCode());
        }
        urlCodes.sort(null);
        return String.join(separator, urlCodes);
    }
    
    public String getAllNames(Queries queryType, List<Integer> ids, Locale locale) {
        return getAllNames(queryType, ids, locale, SqlUtils.COMMA.concat(SqlUtils.SPACE));
    }
    
    public String getAllNames(Queries queryType, List<Integer> ids, Locale locale, String separator) {
        List<String> names = new ArrayList<>();
        for (Integer i = 0; i < ids.size(); i++) {
            names.add(dimById.get(queryType).get(locale).get(ids.get(i)).getName());
        }
        return String.join(separator, names);
    }
    
    public String getAllNamesGen(Queries queryType, List<Integer> ids, Locale locale) {
        return getAllNamesGen(queryType, ids, locale, SqlUtils.COMMA.concat(SqlUtils.SPACE));
    }
    
    public String getAllNamesGen(Queries queryType, List<Integer> ids, Locale locale, String separator) {
        List<String> names = new ArrayList<>();
        for (Integer i = 0; i < ids.size(); i++) {
            names.add(dimById.get(queryType).get(locale).get(ids.get(i)).getNameGen());
        }
        return String.join(separator, names);
    }
    
    public String getAllNamesAcc(Queries queryType, List<Integer> ids, Locale locale) {
        return getAllNamesAcc(queryType, ids, locale, SqlUtils.COMMA.concat(SqlUtils.SPACE));
    }
    
    public String getAllNamesAcc(Queries queryType, List<Integer> ids, Locale locale, String separator) {
        List<String> names = new ArrayList<>();
        for (Integer i = 0; i < ids.size(); i++) {
            names.add(dimById.get(queryType).get(locale).get(ids.get(i)).getNameAcc());
        }
        return String.join(separator, names);
    }

    public String getAllCodesAndNames(Queries queryType, List<Integer> ids, Locale locale) {
        return getAllCodesAndNames(queryType, ids, locale, SqlUtils.COMMA.concat(SqlUtils.SPACE));
    }
    
    public String getAllCodesAndNames(Queries queryType, List<Integer> ids, Locale locale, String separator) {
        List<String> names = new ArrayList<>();
        for (Integer i = 0; i < ids.size(); i++) {
            DimensionValue item = dimById.get(queryType).get(locale).get(ids.get(i));
            names.add(SqlUtils.BRACKET_LEFT
                    .concat(item.getCode())
                    .concat(SqlUtils.BRACKET_RIGHT)
                    .concat(item.getName()));
        }
        return String.join(separator, names);
    }

    public String getAllKeyWords(Queries queryType, List<Integer> ids, Locale locale) {
        return getAllKeyWords(queryType, ids, locale, SqlUtils.COMMA.concat(SqlUtils.SPACE));
    }
    
    public String getAllKeyWords(Queries queryType, List<Integer> ids, Locale locale, String separator) {
        List<String> keyWords = new ArrayList<>();
        for (Integer i = 0; i < ids.size(); i++) {
            keyWords.add(dimById.get(queryType).get(locale).getOrDefault(ids.get(i), DimensionValue.NOT_FOUND).getKeyWords());
        }
        return String.join(separator, keyWords);
    }
    
    public String getNameGenById(Queries queryType, Integer id, Locale locale) {
        return dimById.get(queryType).get(locale).getOrDefault(id, DimensionValue.NOT_FOUND).getNameGen();
    }
    
    public String getNameAccById(Queries queryType, Integer id, Locale locale) {
        return dimById.get(queryType).get(locale).getOrDefault(id, DimensionValue.NOT_FOUND).getNameAcc();
    }
    
    public String getFontAwesomeById(Queries queryType, Integer id, Locale locale) {
        return dimById.get(queryType).get(locale).getOrDefault(id, DimensionValue.NOT_FOUND).getFontAwesome();
    }
    
    public String getNameById(Queries queryType, Integer id, Locale locale) {
        return dimById.get(queryType).get(locale).getOrDefault(id, DimensionValue.NOT_FOUND).getName();
    }
    
    public String getNameByUrlCode(Queries queryType, String urlCode, Locale locale) {
        return dimByUrlCode.get(queryType).get(locale).getOrDefault(urlCode, DimensionValue.NOT_FOUND).getName();
    }
    
    public String getKeyWordsById(Queries queryType, Integer id, Locale locale) {
        return dimById.get(queryType).get(locale).getOrDefault(id, DimensionValue.NOT_FOUND).getKeyWords();
    }
    
    public String getCodeById(Queries queryType, Integer id, Locale locale) {
        return dimById.get(queryType).get(locale).getOrDefault(id, DimensionValue.NOT_FOUND).getCode();
    }
    
    public String getUrlCodeById(Queries queryType, Integer id, Locale locale) {
        return dimById.get(queryType).get(locale).getOrDefault(id, DimensionValue.NOT_FOUND).getUrlCode();
    }
    
    public String getDescriptionById(Queries queryType, Integer id, Locale locale) {
        return dimById.get(queryType).get(locale).getOrDefault(id, DimensionValue.NOT_FOUND).getDescription();
    }
    
    public String getColorById(Queries queryType, Integer id, Locale locale) {
        return dimById.get(queryType).get(locale).getOrDefault(id, DimensionValue.NOT_FOUND).getColor();
    }
    
    public String getUomById(Queries queryType, Integer id, Locale locale) {
        return dimById.get(queryType).get(locale).getOrDefault(id, DimensionValue.NOT_FOUND).getUom();
    }    
}